package com.ehotting.edsta.mqbd.signal.netty.handler;

import com.ehotting.eaf.netty.action.NettyActionFactory;
import com.ehotting.eaf.netty.client.ClientInitializer;
import com.ehotting.eaf.netty.client.TcpClient;
import com.ehotting.eaf.netty.client.TcpClientHelper;
import com.ehotting.eaf.netty.domain.DataAble;
import com.ehotting.eaf.netty.loggers.NettyMsgReceiveLogger;
import com.ehotting.eaf.netty.loggers.NettyMsgSendLogger;
import com.ehotting.eaf.netty.sync.SyncFutureMapHelper;
import com.ehotting.mqbd.api.bean.solver.SolverInfoBean;
import com.ehotting.mqbd.core.manager.AgentLinkManager;
import com.ehotting.mqbd.core.sync.TcpClientMapHelper;
import io.netty.bootstrap.Bootstrap;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

@Component
@Slf4j
public class SiTcpMultiClient {

    /**
     * 读操作空闲秒数
     **/
    @Value("${netty.si.readIdle}")
    private Integer readIdle;
    /**
     * 写操作空闲秒数
     **/
    @Value("${netty.si.writeIdle}")
    private Integer writeIdle;
    /**
     * 读写空闲秒数
     **/
    @Value("${netty.si.allIdle}")
    private Integer allIdle;

    @Resource(name="siNettyActionFactory")
    private NettyActionFactory siNettyActionFactory;

    @Resource(name = "siSyncFutureMapHelper")
    private SyncFutureMapHelper<DataAble> siSyncFutureMapHelper;
    @Autowired
    private NettyMsgSendLogger nettyMsgSendLogger;
    @Autowired
    private AgentLinkManager agentLinkManager;
    @Autowired
    private NettyMsgReceiveLogger solverMsgLogger;
    @Autowired
    private SiIdleStateTrigger siIdleStateTrigger;
    @Autowired
    private TcpClientMapHelper tcpClientMapHelper;

    public TcpClient getByAgentIdAndIp(String module,String agentId, SolverInfoBean solverInfo){
        TcpClient tcpClient = tcpClientMapHelper.get(agentId);

        if(tcpClient==null){
            log.info("tcpClient is null.");
            return createTcpClient( module,agentId, solverInfo);
        }

        if( tcpClient.getChannel()==null ) {
            log.info("tcpClient.getChannel() is null.");
            tcpClientMapHelper.shutdownClient(agentId);
            return createTcpClient( module,agentId, solverInfo);
        }

        if( !tcpClient.getChannel().isActive()) {
            log.info("tcpClient.getChannel().isActive() is {}.",tcpClient.getChannel().isActive());
            agentLinkManager.deleteAgentIdByChannelId(module,tcpClient.getChannel().id().asLongText());
            tcpClientMapHelper.shutdownClient(agentId);
            return createTcpClient( module,agentId, solverInfo);
        }

        return tcpClient;
    }


    public SignalAnalysisTcpClient createTcpClient(String module,String agentId, SolverInfoBean solverInfo){
        log.info("Start createTcpClient.");
        SignalAnalysisTcpClient tcpClient = new SignalAnalysisTcpClient();

        tcpClient.setIp(solverInfo.getIp());
        tcpClient.setPort(Integer.valueOf(solverInfo.getPort()));
        tcpClient.setBootstrap(new Bootstrap());

        ClientInitializer channelInitializer = new ClientInitializer();
        channelInitializer.setAllIdle(allIdle);
        channelInitializer.setReadIdle(readIdle);
        channelInitializer.setWriteIdle(writeIdle);

        channelInitializer.setIdleStateTrigger(siIdleStateTrigger);

        SiClientNettyHandler handler = new SiClientNettyHandler();
        handler.setNettyActionFactory(siNettyActionFactory);
        handler.setNettyMsgReceiveLogger(solverMsgLogger);
        handler.setSiSyncFutureMapHelper(siSyncFutureMapHelper);
        handler.setAgentLinkManager(agentLinkManager);

        channelInitializer.setChannelInboundHandler(handler);
        tcpClient.setChannelInitializer(channelInitializer);

        TcpClientHelper tcpClientHelper = new TcpClientHelper();
        tcpClientHelper.setSyncFutureMapHelper(siSyncFutureMapHelper);
        tcpClientHelper.setLogger(nettyMsgSendLogger);
        tcpClient.setTcpClientHelper(tcpClientHelper);

        handler.setTcpClient(tcpClient);

        try {
            tcpClient.serverStartSync();
            log.info("signalTcpClientMap put by agenId[{}].",agentId);
            tcpClientMapHelper.put(agentId, tcpClient);
            agentLinkManager.setAgentIdByChannelId(module,tcpClient.getChannel().id().asLongText(),agentId);
        } catch (Exception e) {
            e.printStackTrace();
        }
        log.info("Finish createTcpClient.");
        return tcpClient;
    }
}